#include "view_autoui.h"
#include <QTimer>
#include <thread>    
#include <chrono>    

View_AutoUI::View_AutoUI(QWidget *parent) : QWidget(parent) {

    // SharedMemSend sharedMemSend;
    // SharedMemRecv sharedMemRecv;
    // QThread sendThread, recvThread;

    QHBoxLayout *mainLayout = new QHBoxLayout(this);
    QWidget *leftLayout = createLeftPanel();
    createCenterPanel();
    QWidget *rightLayout = createRightPanel();

    BackToMainBtn = new QPushButton("Back", this);
    BackToMainBtn->setFixedSize(80, 40);
    BackToMainBtn->raise();
    connect(BackToMainBtn, &QPushButton::clicked, this, &View_AutoUI::AutoswitchToDesktop);

    mainLayout->addWidget(leftLayout, 1);
    mainLayout->addWidget(gyroDisplay, 2);
    mainLayout->addWidget(rightLayout, 1);

    QTimer *timer = new QTimer(this);
    connect(timer, &QTimer::timeout, [this](){
        static float t = 0;
        t += 0.02;
        
        float roll = 15 * qSin(t);
        float pitch = 20 * qSin(0.8*t); 
        float yaw = 30 * qSin(1.2*t);      
        gyroDisplay->updateOrientation(roll, pitch, yaw);
    });
    timer->start(50);

    sharedMemSend.moveToThread(&sendThread);
    sharedMemRecv.moveToThread(&recvThread);
    QObject::connect(&sendThread, &QThread::started, &sharedMemSend, &SharedMemSend::runSend);
    QObject::connect(&recvThread, &QThread::started, &sharedMemRecv, &SharedMemRecv::runRecv);

    sendThread.start();
    recvThread.start(); 

//    return a.exec();
}

View_AutoUI::~View_AutoUI() {
    sendThread.quit();
    recvThread.quit(); 
}

GyroDisplay::GyroDisplay(QWidget *parent) : QWidget(parent) 
{
    setMaximumSize(300, 300);
}

QWidget* View_AutoUI::createLeftPanel() {
    QWidget *leftpanel = new QWidget;
    leftpanel->setFixedSize(300, 300);  
    QGridLayout *leftGrid = new QGridLayout(leftpanel);
    leftGrid->setSpacing(15);
    //leftpanel->setStyleSheet("background-color:rgb(251, 251, 254); border-radius: 15px;");

    QPushButton *btnForward = new QPushButton(QStringLiteral("↑"), leftpanel);
    QPushButton *btnBackward = new QPushButton(QStringLiteral("↓"), leftpanel);
    QPushButton *btnLeft = new QPushButton(QStringLiteral("←"), leftpanel);
    QPushButton *btnRight = new QPushButton(QStringLiteral("→"), leftpanel);

    leftGrid->addWidget(btnForward, 0, 1);   
    leftGrid->addWidget(btnBackward, 2, 1); 
    leftGrid->addWidget(btnLeft, 1, 0);      
    leftGrid->addWidget(btnRight, 1, 2);    

    QString btnStyle = "QPushButton { font-size: 40px; min-width: 80px; min-height: 80px; }";
    for(auto btn : {btnForward, btnBackward, btnLeft, btnRight}) {
        btn->setStyleSheet(btnStyle);
    }

    leftGrid->setRowStretch(0, 1);
    leftGrid->setRowStretch(2, 1);
    leftGrid->setColumnStretch(0, 1);
    leftGrid->setColumnStretch(2, 1);

    return leftpanel;
}

QWidget* View_AutoUI::createRightPanel() {
    QWidget *rightpanel = new QWidget;
    rightpanel->setFixedSize(300, 300); 
    QVBoxLayout *rightLayout = new QVBoxLayout(rightpanel);
    QPushButton *btnPID = new QPushButton("PID Parameters");
    QPushButton *btnVersion = new QPushButton("Version");
    QPushButton *btnVoltage = new QPushButton("Voltage");

    connect(btnPID, &QPushButton::clicked, this, &View_AutoUI::showPidDialog);
    connect(btnVersion, &QPushButton::clicked, this, &View_AutoUI::showVersionDialog);
    connect(btnVoltage, &QPushButton::clicked, this, &View_AutoUI::showVoltageDialog);

    QString btnStyle = "QPushButton { font-size: 24px; min-height: 60px; }";
    for(auto btn : {btnPID, btnVersion, btnVoltage}) {
        btn->setStyleSheet(btnStyle);
        rightLayout->addWidget(btn);
    }
    
    rightLayout->addStretch();
    return rightpanel; 
}

void View_AutoUI::createCenterPanel() {
    gyroDisplay = new GyroDisplay;
    gyroDisplay->setMinimumSize(200, 200);
}

QDialog* View_AutoUI::createInfoDialog(const QString &title, const QString &content) {
    QDialog *dialog = new QDialog(this);
    dialog->setWindowTitle(title);
    dialog->setFixedSize(800, 400);
    
    QVBoxLayout *layout = new QVBoxLayout(dialog);
    QLabel *label = new QLabel(content);
    label->setAlignment(Qt::AlignCenter);
    layout->addWidget(label);
    
    return dialog;
}

void View_AutoUI::showPidDialog() {
    QDialog *dialog = createInfoDialog("PID Parameter", "  P: 1.2  \n  I: 0.5  \n  D: 0.8  ");
    dialog->exec();
}

void View_AutoUI::showVersionDialog() {
    SendDataToRos.Ctrl.ReadVer = 1;
    QTimer::singleShot(500, this, [this]() {
        QString versionStr = QString("Software: V%1.%2.%3\nHardware: V%4\nBootloader: V%5\n")
                                .arg(1)                       
                                .arg(RecDataFromRos.Ver.SoftWareVer)    
                                .arg(RecDataFromRos.Ver.SoftWareBuildVer)                    
                                .arg(RecDataFromRos.Ver.HardWareVer)     
                                .arg(RecDataFromRos.Ver.BootLoaderVer); 
        QDialog *dialog = createInfoDialog("Version", versionStr);
        dialog->exec();
    });
}

void View_AutoUI::showVoltageDialog() {
    QDialog *dialog = new QDialog(this);
    dialog->setWindowTitle("Voltage");
    dialog->setFixedSize(800, 400);
    
    QVBoxLayout *layout = new QVBoxLayout(dialog);
    QProgressBar *voltageBar = new QProgressBar;
    voltageBar->setRange(0, 100);
    voltageBar->setValue(75);
    voltageBar->setFormat("Current Voltage: 75%");
    
    layout->addWidget(voltageBar);
    dialog->exec();
}



void GyroDisplay::updateOrientation(float roll, float pitch, float yaw) 
{
    m_roll = roll;
    m_pitch = pitch;
    m_yaw = yaw;
    update();
}

void GyroDisplay::paintEvent(QPaintEvent *) 
{
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);
    painter.fillRect(rect(), Qt::black);

    // 坐标系参数
    const int axisLength = qMin(width(), height()) / 3;
    QPoint center = rect().center();

    // 三维坐标系绘制
    painter.save();
    painter.translate(center);
    
    painter.rotate(m_yaw);
    painter.rotate(m_pitch);
    painter.rotate(m_roll);

    // 绘制3D坐标系
    draw3DAxis(painter);
    painter.restore();

    // 绘制姿态指示器
    drawAttitudeIndicator(painter);

    // 显示数值
    painter.setPen(Qt::white);
    painter.drawText(10, 30, QString("Roll:  %1°").arg(m_roll, 0, 'f', 1));
    painter.drawText(10, 60, QString("Pitch: %1°").arg(m_pitch, 0, 'f', 1));
    painter.drawText(10, 90, QString("Yaw:   %1°").arg(m_yaw, 0, 'f', 1));
}

void GyroDisplay::draw3DAxis(QPainter &painter) 
{
    const int axisLength = 100;
    const float perspective = 0.5; // 透视系数
    
    // 三维坐标点（右手坐标系）
    QPoint3D xEnd(axisLength, 0, 0);
    QPoint3D yEnd(0, axisLength, 0);
    QPoint3D zEnd(0, 0, axisLength);

    // 三维转二维投影（简单透视）
    auto project = [&](QPoint3D p) -> QPoint {
        return QPoint(
            p.x() + p.z() * perspective,
            -p.y() + p.z() * perspective  // Y轴取反
        );
    };

    // 绘制X轴（红色）
    painter.setPen(Qt::red);
    QPoint xProj = project(xEnd);
    painter.drawLine(QPoint(0,0), xProj);
    painter.drawText(xProj + QPoint(5,0), "X");

    // 绘制Y轴（绿色）
    painter.setPen(Qt::green);
    QPoint yProj = project(yEnd);
    painter.drawLine(QPoint(0,0), yProj);
    painter.drawText(yProj + QPoint(0,5), "Y");

    // 绘制Z轴（蓝色）
    painter.setPen(Qt::blue);
    QPoint zProj = project(zEnd);
    painter.drawLine(QPoint(0,0), zProj);
    painter.drawText(zProj + QPoint(5,5), "Z");
}

void GyroDisplay::drawAttitudeIndicator(QPainter &painter) 
{
    // 地平仪参数
    const int radius = qMin(width(), height()) / 3;
    QPoint center = rect().center();
    
    painter.save();
    painter.translate(center);
    painter.rotate(m_roll);
    
    // 地平线
    QLinearGradient grad(0, -radius, 0, radius);
    grad.setColorAt(0, QColor(0, 120, 215));  // 天空蓝
    grad.setColorAt(1, QColor(139, 69, 19));  // 大地棕
    
    painter.setBrush(grad);
    painter.setPen(Qt::NoPen);
    painter.drawRect(-radius*2, -m_pitch*2, radius*4, radius*4);
    
    // 中线指示
    painter.setPen(QPen(Qt::white, 2));
    painter.drawLine(-radius, 0, radius, 0);
    painter.drawEllipse(QPoint(0,0), radius/10, radius/10);
    
    painter.restore();
}
